﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

using Client.Common;
using Client.DAL;

using Models;

using Newtonsoft.Json;

using Panuon.UI.Silver;

using Prism.Commands;
using Prism.Mvvm;

namespace Client.ViewModels
{
    public class UserManageViewModel : BindableBase
    {
        #region 绑定属性

        #region 管理窗口

        //用户列表
        private ObservableCollection<UserModel> _userList;

        public ObservableCollection<UserModel> UserList
        {
            get { return _userList; }
            set { SetProperty(ref _userList, value, "UserList"); }
        }

        //选择的用户
        private object _selectedUser;

        public object SelectedUser
        {
            get { return _selectedUser; }
            set { SetProperty(ref _selectedUser, value, "SelectedUser"); }
        }

        //显示禁用的用户
        private bool _showDisabledUser;

        public bool ShowDisabledUser
        {
            get { return _showDisabledUser; }
            set { SetProperty(ref _showDisabledUser, value, "ShowDisabledUser"); }
        }

        //启用用户按钮状态
        private bool _btnUserEnableWorking;

        public bool BtnUserEnableWorking
        {
            get { return _btnUserEnableWorking; }
            set { SetProperty(ref _btnUserEnableWorking, value, "BtnUserEnableWorking"); }
        }

        //禁用用户按钮状态
        private bool _btnUserDisableWorking;

        public bool BtnUserDisableWorking
        {
            get { return _btnUserDisableWorking; }
            set { SetProperty(ref _btnUserDisableWorking, value, "BtnUserDisableWorking"); }
        }

        //刷新按钮状态
        private bool _btnUserRefreshWorking;

        public bool BtnUserRefreshWorking
        {
            get { return _btnUserRefreshWorking; }
            set { SetProperty(ref _btnUserRefreshWorking, value, "BtnUserRefreshWorking"); }
        }

        //载入界面状态
        private Visibility _userRunning;

        public Visibility UserRunning
        {
            get { return _userRunning; }
            set { SetProperty(ref _userRunning, value, "UserRunning"); }
        }

        //载入动画状态
        private bool _userLoading;

        public bool UserLoading
        {
            get { return _userLoading; }
            set { SetProperty(ref _userLoading, value, "UserLoading"); }
        }

        #endregion 管理窗口

        #region 用户编辑窗口

        //编辑窗口的用户对象
        private UserModel _userEditUser;

        public UserModel UserEditUser
        {
            get { return _userEditUser; }
            set { SetProperty(ref _userEditUser, value, "UserEditUser"); }
        }

        //保存按钮状态
        private bool _btnUserEditSaveWorking;

        public bool BtnUserEditSaveWorking
        {
            get { return _btnUserEditSaveWorking; }
            set { SetProperty(ref _btnUserEditSaveWorking, value, "BtnUserEditSaveWorking"); }
        }

        #endregion 用户编辑窗口

        #endregion 绑定属性

        #region 属性

        private Window _userEditWindow;

        private string _userEditOpenType = "new";

        #endregion 属性

        #region 命令

        public DelegateCommand UserAddCommand { get; private set; }
        public DelegateCommand UserEditCommand { get; private set; }
        public DelegateCommand UserEnableCommand { get; private set; }
        public DelegateCommand UserDisableCommand { get; private set; }
        public DelegateCommand UserRefreshCommand { get; private set; }

        public DelegateCommand UserEditNewCommand { get; private set; }
        public DelegateCommand<PasswordBox> UserEditSaveCommand { get; private set; }

        #endregion 命令

        #region 构造函数

        public UserManageViewModel()
        {
            UserList = new ObservableCollection<UserModel>();
            SelectedUser = null;
            UserLoading = false;
            UserRunning = Visibility.Hidden;
            BtnUserDisableWorking = false;
            BtnUserEnableWorking = false;
            BtnUserDisableWorking = false;
            UserAddCommand = new DelegateCommand(UserAdd);
            UserEditCommand = new DelegateCommand(UserEdit);
            UserEnableCommand = new DelegateCommand(EnableUser);
            UserDisableCommand = new DelegateCommand(DisableUser);
            UserRefreshCommand = new DelegateCommand(RefreshUser);

            UserEditUser = new UserModel();
            BtnUserEditSaveWorking = false;
            UserEditNewCommand = new DelegateCommand(UserEditNew);
            UserEditSaveCommand = new DelegateCommand<PasswordBox>(UserEditSave);

            RefreshUser();
        }

        #endregion 构造函数

        #region 方法

        #region 管理窗口

        #region 打开新增用户

        private void UserAdd()
        {
            _userEditOpenType = "new";
            _userEditWindow = new Views.UserEditView()
            {
                Title = "用户新增",
                Owner = Comm.Shell,
                DataContext = this
            };
            UserEditUser = new UserModel();
            _userEditWindow.ShowDialog();
            _userEditWindow = null;
        }

        #endregion 打开新增用户

        #region 打开用户修改窗口

        private StateModel getUserState;

        private async void UserEdit()
        {
            if (SelectedUser is null || !(SelectedUser is UserModel um))
            {
                Comm.ShowErr("必须选择要修改的用户！", "修改用户");
                return;
            }

            try
            {
                getUserState = new StateModel { CurStep = Steps.Send };
                UserSrv.GetUserInfo(GetUserCallback, um.Id);
                await getUserState.CheckState(10);
                um = GenUser();
            }
            catch (Exception ex)
            {
                Comm.ShowErr(ex.Message, "修改用户");
            }

            if (um is null)
            {
                Comm.ShowErr(getUserState.ErrStr, "修改用户");
                return;
            }
            UserEditUser = um;
            _userEditOpenType = "edit";
            _userEditWindow = new Views.UserEditView()
            {
                Owner = Comm.Shell,
                Title = "用户信息修改",
                DataContext = this
            };
            _userEditWindow.ShowDialog();
            _userEditWindow = null;
        }

        private UserModel GenUser()
        {
            UserModel um = null;
            try
            {
                if (getUserState.CurStep == Steps.Succ)
                    um = JsonConvert.DeserializeObject<UserModel>(getUserState.RM.Data.ToString());
            }
            catch (Exception ex)
            {
                getUserState.RM = getUserState.RM ?? new RetModel { };
                getUserState.RM.ErrInfo = ex.Message;
                getUserState.RM.ErrCode = "0000";
            }
            return um;
        }

        private void GetUserCallback(RetModel rm)
        {
            getUserState.RM = rm;
            getUserState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
        }

        #endregion 打开用户修改窗口

        #region 启用用户

        private StateModel enableState;

        private async void EnableUser()
        {
            if (SelectedUser is null || !(SelectedUser is UserModel um))
            {
                Comm.ShowErr("必须选择要启用的用户！", "启用用户");
                return;
            }
            var rst = MessageBoxX.Show("是否确认要启用当前选中的用户？", "启用用户", Comm.Shell, MessageBoxButton.YesNo, new MessageBoxXConfigurations()
            {
                Topmost = false,
                MessageBoxStyle = MessageBoxStyle.Modern,
                WindowStartupLocation = WindowStartupLocation.CenterOwner
            });
            if (rst != MessageBoxResult.Yes)
                return;
            BtnUserEnableWorking = true;
            try
            {
                enableState = new StateModel { CurStep = Steps.Send };
                UserSrv.EnableUser(EnableUserCallback, um.Id);
                await enableState.CheckState(10);
            }
            catch (Exception ex)
            {
                Comm.ShowErr(ex.Message, "启用用户");
                BtnUserEnableWorking = false;
                return;
            }
            um = null;
            if (enableState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(enableState.ErrStr, "启用用户");
                BtnUserEnableWorking = false;
                return;
            }
            RefreshUser();
            BtnUserEnableWorking = false;
        }

        private void EnableUserCallback(RetModel rm)
        {
            enableState.RM = rm;
            enableState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
        }

        #endregion 启用用户

        #region 禁用用户

        private async void DisableUser()
        {
            if (SelectedUser is null || !(SelectedUser is UserModel um))
            {
                Comm.ShowErr("必须选择要禁用的用户！", "禁用用户");
                return;
            }
            var rst = MessageBoxX.Show("是否确认要禁用当前选中的用户？", "禁用用户", Comm.Shell, MessageBoxButton.YesNo, new MessageBoxXConfigurations()
            {
                Topmost = false,
                MessageBoxStyle = MessageBoxStyle.Modern,
                WindowStartupLocation = WindowStartupLocation.CenterOwner
            });
            if (rst != MessageBoxResult.Yes)
                return;
            BtnUserDisableWorking = true;
            string err = "";
            try
            {
                enableState = new StateModel() { CurStep = Steps.Send };
                UserSrv.DisableUser(DisableUserCallback, um.Id);
                await enableState.CheckState(10);
            }
            catch (Exception ex)
            {
                Comm.ShowErr(ex.Message, "禁用用户");
                BtnUserDisableWorking = false;
                return;
            }
            if (enableState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(err, "禁用用户");
                BtnUserDisableWorking = false;
                return;
            }
            RefreshUser();
            BtnUserDisableWorking = false;
        }

        private void DisableUserCallback(RetModel rm)
        {
            enableState.RM = rm;
            enableState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
        }

        #endregion 禁用用户

        #region 刷新列表

        private void RefreshUser()
        {
            GetUserList();
        }

        #endregion 刷新列表

        #region 读取用户列表

        private StateModel getUserListState;

        private async void GetUserList()
        {
            UserLoading = true;
            UserRunning = Visibility.Visible;
            UserList.Clear();
            byte state = 0;
            if (ShowDisabledUser)
                state = 3;
            getUserListState = new StateModel { CurStep = Steps.Send };
            UserSrv.GetUserList(GetUserListCallback, state);
            await getUserListState.CheckState(10);
            List<UserModel> l = GenUserList();
            if (l != null && l?.Count > 0)
                UserList.AddRange(l);
            UserLoading = false;
            UserRunning = Visibility.Hidden;
        }

        private List<UserModel> GenUserList()
        {
            List<UserModel> l = null;
            try
            {
                l = JsonConvert.DeserializeObject<List<UserModel>>(getUserListState.RM.Data.ToString());
            }
            catch (Exception ex)
            {
                getUserListState.RM.ErrCode = "0000";
                getUserListState.RM.ErrInfo = ex.Message;
            }
            return l;
        }

        private void GetUserListCallback(RetModel rm)
        {
            getUserListState.RM = rm;
            getUserListState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
        }

        #endregion 读取用户列表

        #endregion 管理窗口

        #region 编辑窗口

        #region 新增

        private void UserEditNew()
        {
            UserEditUser = new UserModel();
            _userEditOpenType = "new";
        }

        #endregion 新增

        #region 保存

        private StateModel saveUserState;

        private async void UserEditSave(PasswordBox p)
        {
            BtnUserEditSaveWorking = true;
            try
            {
                CheckSave(p);
                if (!string.IsNullOrEmpty(p.Password))
                    UserEditUser.Password = Taxhui.Utils.CryptUtils.MD5Crypt.MD32Crypt(p.Password);
                saveUserState = new StateModel { CurStep = Steps.Send };
                if (_userEditOpenType == "new")
                    UserSrv.AddUser(SaveUserCallback, UserEditUser);
                if (_userEditOpenType == "edit")
                    UserSrv.EditUser(SaveUserCallback, UserEditUser);
                await saveUserState.CheckState(10);
            }
            catch (Exception ex)
            {
                Comm.ShowErr(ex.Message, "保存用户");
                BtnUserEditSaveWorking = false;
                return;
            }
            if (saveUserState.CurStep == Steps.Succ)
            {
                RefreshUser();
            }
            else
            {
                Comm.ShowErr(saveUserState.ErrStr, "保存用户");
            }
            if (_userEditOpenType == "edit")
                _userEditWindow.Close();
            else
                UserEditNew();
            BtnUserEditSaveWorking = false;
        }

        private void CheckSave(PasswordBox p)
        {
            if (string.IsNullOrEmpty(UserEditUser.UserName))
            {
                throw new Exception("用户名不能为空！");
            }
            if (string.IsNullOrEmpty(p.Password) && string.IsNullOrEmpty(UserEditUser.Password))
            {
                throw new Exception("密码不能为空");
            }
            if (string.IsNullOrEmpty(UserEditUser.RealName))
            {
                throw new Exception("用户姓名不能为空！");
            }
            if (_userEditOpenType == "edit" && UserEditUser.Id <= 0)
            {
                throw new Exception("必须指定要修改的用户");
            }
        }

        private void SaveUserCallback(RetModel rm)
        {
            saveUserState.RM = rm;
            saveUserState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
        }

        #endregion 保存

        #endregion 编辑窗口

        #endregion 方法
    }
}